home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / pstools / psnup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  6.0 KB  |  265 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    psnup -
  19.  *        Do n-up printing of PostScript files 
  20.  *
  21.  *    To compile:
  22.  *        cc psnup.c -o psnup 
  23.  *
  24.  *                Paul Haeberli - 1993
  25.  */
  26. #include "stdio.h"
  27. #include "math.h"
  28. #include "ctype.h"
  29.  
  30. #define DEFPWIDTH     (72.0*8.50)    /* page width and weight */
  31. #define DEFPHEIGHT     (72.0*11.0)
  32.  
  33. #define SPACE         (72.0*0.2)    /* space between */
  34. #define MARGIN         (72.0*0.2)    /* space around */
  35.  
  36. #define SWIDTH         (72.0*8.50)    /* sheet width and height */
  37. #define SHEIGHT     (72.0*11.0)
  38.  
  39. #define INBUFSIZE    4096
  40. #define MAXPAGES    1000
  41.  
  42. char buf[INBUFSIZE];
  43. int secstart[MAXPAGES];
  44. int secend[MAXPAGES];
  45. int trailstart;
  46. int trailend;
  47. float pwidth, pheight;
  48.  
  49. void printheader(dosettrans)
  50. int dosettrans;
  51. {
  52.     printf("%%!PS-Adobe-2.0\n");
  53.     printf("%%%%EndComments\n");
  54.     printf("/REALshowpage /showpage load def\n"); 
  55.     printf("/showpage { } def\n");
  56.     if(dosettrans)
  57.     psprintcortab();
  58. }
  59.  
  60. int indexpages(inf)
  61. FILE *inf;
  62. {
  63.     int i, n, before, after;
  64.  
  65.     n = 0;
  66.     trailstart = 0;
  67.     trailend = 0;
  68.     while(fgets(buf,INBUFSIZE,inf)) {
  69.     if(strncmp(buf,"%%Page:",7) == 0) {
  70.         after = ftell(inf);
  71.         if(n>0)
  72.         secend[n-1] = before;
  73.         secstart[n] = after; 
  74.         n++;
  75.     } else if(strncmp(buf,"%%Trailer",9) == 0) {
  76.         after = ftell(inf);
  77.         if(n>0)
  78.         secend[n-1] = before;
  79.         trailstart = after;
  80.         trailend = sizeoffile(inf);
  81.         return n;
  82.     }
  83.     before = ftell(inf);
  84.     }
  85.     secend[n-1] = ftell(inf);
  86.     return n;
  87. }
  88.  
  89. void putsection(inf,start,nbytes)
  90. FILE *inf;
  91. int start, nbytes;
  92. {
  93.     int nr;
  94.  
  95.     fseek(inf,start,0);
  96.     while(nbytes>0) {
  97.     if(!fgets(buf,INBUFSIZE,inf)) {
  98.         fprintf(stderr,"psnup: bad read in putsection\n");
  99.         exit(1);
  100.     }
  101.     nr = strlen(buf);
  102.     nbytes -= nr;
  103.     if(buf[0] != '%')
  104.         fputs(buf,stdout);
  105.     }
  106.     if(nbytes != 0) {
  107.     fprintf(stderr,"psnup: strange read in putsection %d\n",nbytes);
  108.     exit(1);
  109.     }
  110. }
  111.  
  112. void putpage(inf,pageno,npages)
  113. FILE *inf;
  114. int pageno, npages;
  115. {
  116.     int nbytes;
  117.  
  118.     if(pageno<npages && pageno>=0) {
  119.     nbytes = secend[pageno]-secstart[pageno];
  120.     putsection(inf,secstart[pageno],nbytes);
  121.     }
  122. }
  123.  
  124. void dosave(inf)
  125. FILE *inf;
  126. {
  127.     printf("gsave\n");
  128. }
  129.  
  130. void dorestore(inf)
  131. FILE *inf;
  132. {
  133.     if(trailstart) 
  134.     putsection(inf,trailstart,trailend-trailstart);
  135.     printf("grestore\n"); 
  136. }
  137.  
  138. void psnup(inf,npages,nx,ny)
  139. FILE *inf;
  140. int npages, nx, ny;
  141. {
  142.     int x, y, nperside, nsides, pageno, side;
  143.     float fscale, qx, qy, ox, oy;
  144.  
  145.     qx = (SWIDTH-2*MARGIN)/nx;
  146.     qy = (SHEIGHT-2*MARGIN)/ny;
  147.     nperside = nx*ny;
  148.     nsides = 1+((npages-1)/nperside);
  149.     if((qx/qy) < (pwidth/pheight)) 
  150.     fscale = (qx-SPACE)/pwidth;
  151.     else 
  152.     fscale = (qy-SPACE)/pheight;
  153.     ox = MARGIN+(qx-pwidth*fscale)/2.0;
  154.     oy = MARGIN+(qy-pheight*fscale)/2.0;
  155.  
  156. /* put out the sheets */
  157.     pageno = 0;
  158.     for(side=0; side<nsides; ) {
  159.         printf("%%%%Page: page%d %d\n",side+1,side+1);
  160.     for(y=0; y<ny; y++) {
  161.         for(x=0; x<nx; x++) {
  162.         if(pageno<npages) {
  163.             printf("gsave\n");
  164.             printf("%f %f translate\n",x*qx+ox,(ny-1-y)*qy+oy);
  165.             printf("%f %f scale\n",fscale,fscale);
  166.  
  167.             dosave(inf);
  168.             printf("newpath\n");
  169.             printf("%f %f moveto\n",0.0,0.0);
  170.             printf("%f %f lineto\n",pwidth,0.0);
  171.             printf("%f %f lineto\n",pwidth,pheight);
  172.             printf("%f %f lineto\n",0.0,pheight);
  173.             printf("closepath clip newpath\n");
  174.             putsection(inf,0,secstart[0]);
  175.             putpage(inf,pageno,npages);
  176.             dorestore(inf);
  177.  
  178.             printf("0 setgray\n");
  179.             printf("0.1 setlinewidth\n");
  180.             printf("newpath\n");
  181.             printf("%f %f moveto\n",0.0,0.0);
  182.             printf("%f %f lineto\n",pwidth,0.0);
  183.             printf("%f %f lineto\n",pwidth,pheight);
  184.             printf("%f %f lineto\n",0.0,pheight);
  185.             printf("closepath stroke\n");
  186.             printf("grestore\n");
  187.         }
  188.         pageno++;
  189.         }
  190.     }
  191.     printf("REALshowpage\n");
  192.     side++;
  193.     }
  194. }
  195.  
  196. main(argc,argv)
  197. int argc;
  198. char **argv;
  199. {
  200.     FILE *inf;
  201.     int npages, i, dosettrans;
  202.     int nx, ny;
  203.  
  204.     if(argc<4) {
  205.      fprintf(stderr,"\nusage: psnup in.ps nx ny [-s pagesizex pagesizey] [-nosettrans] > out.ps\n");
  206.      fprintf(stderr,"\nThis will print two by two array of pages on each side of the paper: \n");
  207.      fprintf(stderr,"    psnup in.ps 2 2 > out.ps\n");
  208.      fprintf(stderr,"\nYou can also specify the size of the input pages like this: \n");
  209.      fprintf(stderr,"    psnup in.ps 1 2 -s 17.53 13.63 > out.ps\n");
  210.      fprintf(stderr,"\n");
  211.      exit(1);
  212.     }
  213.     nx = atoi(argv[2]);
  214.     ny = atoi(argv[3]);
  215.     pwidth = DEFPWIDTH;
  216.     pheight = DEFPHEIGHT;
  217.     dosettrans = 1;
  218.     for(i=4; i<argc; i++) {
  219.     if(argv[i][0] == '-') {
  220.         switch(argv[i][1]) {
  221.         case 's':
  222.             i++;
  223.             pwidth = 72.0*atof(argv[i]);
  224.             i++;
  225.             pheight = 72.0*atof(argv[i]);
  226.             break;
  227.         case 'n':
  228.             dosettrans = 0;
  229.             break;
  230.         }
  231.     }    
  232.     }
  233.     inf = fopen(argv[1],"r");
  234.     if(!inf) {
  235.      fprintf(stderr,"psnup: can't open %s\n",argv[1]);
  236.      exit(1);
  237.     }
  238.     npages = indexpages(inf);
  239.  
  240.     fprintf(stderr,"Document pages %d\n",npages);
  241. #ifdef DEBUG
  242.     for(i=0; i<npages; i++) 
  243.     fprintf(stderr,"page %d start %d finish %d\n",i,secstart[i],secend[i]);
  244.     fprintf(stderr,"trailstart %d trailend %d\n",trailstart,trailend);
  245. #endif
  246.  
  247.     if(npages == 0) {
  248.     secend[0] = sizeoffile(inf);
  249.     secstart[0] = 0;
  250.     npages = 1;
  251.     } 
  252.  
  253. /* put out the master preamble */
  254.     psoutfile(stdout);
  255.     printheader(dosettrans);
  256.     psgsave();
  257.  
  258. /* put out the pages*/
  259.     psnup(inf,npages,nx,ny);
  260.     psgrestore();
  261.     printf("%%%%EOF\n");
  262.     exit(0);
  263. }
  264.  
  265.